// VBlock.h
// This file defines class VBlock
#ifndef VBLOCK_H
#define VBLOCK_H

#include "crossbit/VInst.h"
#include "crossbit/VBlockBuilder.h"
#include <vector>
#include <iterator>
#include <iostream>
#include <iomanip>

namespace crossbit {

    // For the beginning, VBlock is just an wrap class for vector<VInst *>
    class VBlock {
        //								friend void VBlockBuilder::add(VInst *inst);
        //								friend VBlock* VBlockBuilder::wrapUp(XTMemAddr pc);

        public:
            typedef std::vector<VInst *>::iterator				vb_iterator;
            typedef std::vector<VInst *>::const_iterator			vb_const_iterator;
            typedef std::vector<VInst *>::reverse_iterator		vb_reverse_iterator;
            typedef std::vector<VInst *>::const_reverse_iterator	vb_const_reverse_iterator;

            VBlock(XTMemAddr enter_spc) 
                : vb_enter_spc(enter_spc) { vb_next_spc = 0;}

            ~VBlock() { clear(); }

            void push_back(VInst * const inst) { vb_ilist.push_back(inst); }

            vb_iterator insert(vb_iterator it, VInst * const vinst) 
            { return vb_ilist.insert(it, vinst); }

            vb_iterator erase(vb_iterator it) 
            { return vb_ilist.erase(it); }

            XTUint32 size() const { return vb_ilist.size(); }

            bool empty() const { return vb_ilist.empty(); }

            void setVbIlist(XTInt32 index, VInst *inst)
            {
                if( index >= 0 && index <= vb_ilist.size() )
                    vb_ilist[index] = inst;
                else
                    return;
            }

            // instruction iterator methods
            vb_iterator		    		begin()			{ return vb_ilist.begin(); }
            vb_const_iterator			begin()	const	{ return vb_ilist.begin(); }
            vb_iterator		    		end()		    { return vb_ilist.end(); }
            vb_const_iterator			end()	const	{ return vb_ilist.end(); }
            vb_reverse_iterator			rbegin()		{ return vb_ilist.rbegin(); }
            vb_const_reverse_iterator	rbegin()const	{ return vb_ilist.rbegin(); }
            vb_reverse_iterator	    	rend()			{ return vb_ilist.rend(); }
            vb_const_reverse_iterator  	rend()	const	{ return vb_ilist.rend(); }

            void clear() 
            {
                for (vb_iterator it = vb_ilist.begin(); it != vb_ilist.end(); ++it)
                    delete (*it);
                vb_ilist.clear();
            }

            XTMemAddr enterSPC()	const	{ return vb_enter_spc; }
            XTMemAddr nextSPC()	const	{ return vb_next_spc; }

            void setVbNextSpc( XTMemAddr spc )
            {
                vb_next_spc = spc;
                return;
            }

            void print(std::ostream &os) {
                vb_iterator I = begin(),
                            E = end();

                for (int i = 0; I != E; ++I, ++i) {
                    os << std::setw(3) << std::right << i << ": " << **I << std::endl;
                }
            }
            void setFlagsCount(int count)
            {
                flagsCount = count;
            }

            void setTotalCount(int count)
            {
                totalCount = count;
            }

            int getFlagsCount()
            {
                return flagsCount;
            }

            int getTotalCount()
            {
                return totalCount;
            }
        private:
            XTMemAddr vb_enter_spc;
            XTMemAddr vb_next_spc;
            std::vector<VInst *> vb_ilist;

            // forbid copy constructor
            VBlock(const VBlock &) {}

            // forbid copy assignment
            VBlock& operator=(const VBlock &) 
            { return *this; }     
            int flagsCount;
            int totalCount;
    };

}

#endif
